home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / languags / cc.1 < prev    next >
Text File  |  1989-04-26  |  43KB  |  1,732 lines

  1. Path: xanth!ames!purdue!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!sun!rishathra!page
  2. From: page%rishathra@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i099:  cc - unix-like front end for lattice 5.x
  5. Message-ID: <101403@sun.Eng.Sun.COM>
  6. Date: 26 Apr 89 21:36:34 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1721
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: bader+@andrew.cmu.edu (Miles Bader)
  12. Posting-number: Volume 89, Issue 99
  13. Archive-name: languages/cc.1
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    Makefile
  24. #    README
  25. #    builtins.make
  26. #    cc.c
  27. #    cc.doc
  28. #    config.h
  29. #    dstr.c
  30. #    dstr.h
  31. #    err.c
  32. #    list.c
  33. #    list.h
  34. #    op.c
  35. #    op.h
  36. #    options.c
  37. #    options.h
  38. # This is archive 1 of a 1-part kit.
  39. # This archive created: Wed Apr 26 14:31:28 1989
  40. echo "extracting Makefile"
  41. sed 's/^X//' << \SHAR_EOF > Makefile
  42. XDEBUG=    -O
  43. XOPTS=    +no-stack-check
  44. XFLAGS=    $(DEBUG) $(OPTS)
  45. XCFLAGS= $(FLAGS) $(DEFINES)
  46. XLFLAGS= $(FLAGS)
  47. X
  48. XLIBS=
  49. X
  50. XTARGET=    cc
  51. XOBJS=    cc.o list.o dstr.o err.o op.o options.o
  52. X
  53. X$(TARGET):    $(OBJS)
  54. X    ${CC} $(LFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
  55. X
  56. X$(OBJS): common.h
  57. Xcc.o:    list.h dstr.h op.h options.h config.h
  58. Xcommon.h: dbug.h
  59. Xoptions.o: options.h
  60. Xdstr.o: dstr.h
  61. Xlist.o: list.h
  62. Xop.o: op.h
  63. SHAR_EOF
  64. echo "extracting README"
  65. sed 's/^X//' << \SHAR_EOF > README
  66. XSimple changes to cc's defaults can be made in config.h.  If you make a not-
  67. Xso-simple change, to implement some new feature, please send me back the
  68. Xchanges.  My email address is bader+@andrew.cmu.edu.
  69. X
  70. XThe Makefile and builtins.make (which goes in s: and defines default rules)
  71. Xare for the version of make that comes with pcc 3.0 (although I just noticed,
  72. Xit's ignoring time-stamps!  Anyone got a better make?)
  73. X
  74. X-Miles
  75. SHAR_EOF
  76. echo "extracting builtins.make"
  77. sed 's/^X//' << \SHAR_EOF > builtins.make
  78. XCC=cc
  79. X
  80. X.SUFFIXES: .c .o
  81. X
  82. X.c.o:
  83. X    ${CC} -c ${CFLAGS} $<
  84. SHAR_EOF
  85. echo "extracting cc.c"
  86. sed 's/^X//' << \SHAR_EOF > cc.c
  87. X/*
  88. X * cc -- unix-like compiler driver for amiga lattice c
  89. X *
  90. X * adapted for lattice version 5.0 and extensively modified
  91. X *   by Miles Bader, from the original by Fred Fish (copyright
  92. X *   follows).
  93. X */
  94. X
  95. X/************************************************************************
  96. X *                                    *
  97. X *            Copyright (c) 1985, Fred Fish            *
  98. X *                All Rights Reserved                *
  99. X *                                    *
  100. X *    This software and/or documentation is released into the        *
  101. X *    public domain for personal, non-commercial use only.        *
  102. X *    Limited rights to use, modify, and redistribute are hereby    *
  103. X *    granted for non-commercial purposes, provided that all        *
  104. X *    copyright notices remain intact and all changes are clearly    *
  105. X *    documented.  The author makes no warranty of any kind with    *
  106. X *    respect to this product and explicitly disclaims any implied    *
  107. X *    warranties of merchantability or fitness for any particular    *
  108. X *    purpose.                            *
  109. X *                                    *
  110. X ************************************************************************
  111. X */
  112. X
  113. X#include <stdio.h>
  114. X#include <stdlib.h>
  115. X#include <string.h>
  116. X
  117. X#include <dos.h>
  118. X#include <proto/dos.h>
  119. X#include <ios1.h> /* magic */
  120. X
  121. X#include "common.h"
  122. X#include "list.h"
  123. X#include "dstr.h"
  124. X#include "op.h"
  125. X#include "options.h"
  126. X
  127. X#include "config.h"
  128. X
  129. Xstatic char *locate(char *file,struct list *list);    /* find a file */
  130. Xstatic void cleanObjects(int mustExist);    /* Remove .o for link and go mode */
  131. Xstatic int makeObjs();            /* Reduce to list of object files */
  132. Xstatic int parseCommandLine();        /* Deal with command line */
  133. Xstatic int compile(struct op *op);    /* Translate from .c to .o */
  134. Xstatic int assemble(struct op *op);    /* Translate from .s to .o */
  135. Xstatic int link();            /* Gather .o's into executable */
  136. Xstatic int runCmd(struct dstr *cmd);
  137. X
  138. X#ifdef amiga
  139. X#define CHECK_ABORT chkabort()
  140. X#else
  141. X#define CHECK_ABORT                /* NULL expansion */
  142. X#endif    /* amiga */
  143. XDBUG_GLOBALS
  144. X
  145. X/*
  146. X *    flags set by command line arguments
  147. X */
  148. Xstatic int debugLevel=DEFAULT_DEBUGLEVEL;    /* -g (debugging level) */
  149. X
  150. Xstruct list *libDirs=NULL;
  151. Xstruct list *incDirs=NULL;
  152. Xstruct list *binDirs=NULL;
  153. Xstruct list *defines=NULL;
  154. Xstruct list *undefines=NULL;
  155. Xstruct list *libs=NULL;
  156. X
  157. Xstruct list *pass1PassThrus=NULL;
  158. Xstruct list *pass2PassThrus=NULL;
  159. Xstruct list *optPassThrus=NULL;
  160. Xstruct list *linkPassThrus=NULL;
  161. X
  162. Xstruct list *ops=NULL;
  163. X
  164. Xstatic char *outfile=DEFAULT_EXEC;    /* output file name from linker */
  165. Xstatic char *tempDir=TEMPDIR;        /* where to keep quad files */
  166. Xstatic char *sinkFile=SINKFILE;        /* where to put output from passes */
  167. X
  168. Xstruct dstr *cmdLine=NULL;
  169. Xstatic int abortmsg()
  170. X{
  171. X    if(options_IsSet(OPT_ECHO))
  172. X    fprintf(stderr,"cc: aborting\n");
  173. X    return 1; /* abort */
  174. X}
  175. X
  176. Xstatic int cleanup(status)
  177. Xint status;
  178. X{
  179. X    if(cmdLine!=NULL)    dstr_Free(cmdLine);
  180. X
  181. X    if(libDirs!=NULL)    list_Free(libDirs);
  182. X    if(incDirs!=NULL)    list_Free(incDirs);
  183. X    if(binDirs!=NULL)    list_Free(binDirs);
  184. X    if(defines!=NULL)    list_Free(defines);
  185. X    if(undefines!=NULL)    list_Free(undefines);
  186. X    if(libs!=NULL)    list_Free(libs);
  187. X
  188. X    if(pass1PassThrus!=NULL)    list_Free(pass1PassThrus);
  189. X    if(pass2PassThrus!=NULL)    list_Free(pass2PassThrus);
  190. X    if(optPassThrus!=NULL)    list_Free(optPassThrus);
  191. X    if(linkPassThrus!=NULL)    list_Free(linkPassThrus);
  192. X
  193. X    if(ops!=NULL)    list_Free(ops);
  194. X
  195. X    return status;
  196. X}
  197. X
  198. Xstatic void init()
  199. X{
  200. X    int *opt;
  201. X
  202. X    options_Init();
  203. X    for(opt=defaultOptions; *opt!=0; opt++)
  204. X    options_Set(*opt);
  205. X
  206. X    cmdLine=dstr_Create(30);        /* global command buffer */
  207. X
  208. X    libDirs=list_Create((void **)libDirsInit);
  209. X    incDirs=list_Create((void **)incDirsInit);
  210. X    binDirs=list_Create((void **)binDirsInit);
  211. X    defines=list_Create((void **)definesInit);
  212. X    undefines=list_Create((void **)undefinesInit);
  213. X    libs=list_Create((void **)libsInit);
  214. X
  215. X    pass1PassThrus=list_Create(NULL);
  216. X    pass2PassThrus=list_Create(NULL);
  217. X    optPassThrus=list_Create(NULL);
  218. X    linkPassThrus=list_Create(NULL);
  219. X
  220. X    ops=list_Create(NULL);
  221. X    list_SetFree(ops,op_Free);
  222. X}
  223. X
  224. Xvoid main(argc, argv)
  225. Xint argc;
  226. Xchar *argv[];
  227. X{
  228. X    int status;
  229. X
  230. X    DBUG_ENTER("main");
  231. X
  232. X    onexit(cleanup);
  233. X    init();
  234. X
  235. X    onbreak(abortmsg);
  236. X
  237. X    if(parseCommandLine(argc,argv)==0)
  238. X    fatal("no files specified");
  239. X
  240. X    cleanObjects(FALSE);    /* get rid of existing object files if any */
  241. X
  242. X    status=makeObjs();
  243. X    if(status==0 && options_IsSet(OPT_LINK)){
  244. X    status=link();
  245. X    if(list_GetLen(ops)==1)
  246. X        cleanObjects(TRUE);
  247. X    }
  248. X
  249. X    exit(status);
  250. X}
  251. X
  252. X/*
  253. X *    The following macro is used to allow optional whitespace between
  254. X *    an option and it's argument.  Argp is left pointing at the option
  255. X *    and argv and argc are adjusted accordingly if necessary.
  256. X *
  257. X *    Note that there is no check for missing option arguments.  In
  258. X *    particular, -o -V will blindly take -V as the output file name.
  259. X *
  260. X */
  261. X
  262. X#define XARG(argc,argv,argp) {if(*++argp=='\0'){argp=(*argv++);argc--;}}
  263. X
  264. Xstatic int parseCommandLine(argc,argv)
  265. Xint argc;
  266. Xchar **argv;
  267. X{
  268. X    register char *argp;    
  269. X
  270. X    DBUG_ENTER("parseCommandLine");
  271. X
  272. X    argc--;
  273. X    argv++;
  274. X    while(argc-- > 0){
  275. X    CHECK_ABORT;
  276. X
  277. X    argp=*argv++;
  278. X
  279. X    if(*argp=='+')
  280. X        options_SetByName(argp+1);
  281. X    else if(*argp!='-')    
  282. X        list_Add(ops,(void *)op_Create(argp));
  283. X    else
  284. X        switch(*++argp){
  285. X        case 'c':
  286. X            options_Clear(OPT_LINK);    /* don't link object modules */
  287. X            break;
  288. X        case 'p':            /* pass thru args to a pass */
  289. X            switch(*++argp){
  290. X            case '1':        /* pass 1 */
  291. X                XARG(argc,argv,argp);            
  292. X                list_Add(pass1PassThrus,argp);
  293. X                break;
  294. X            case '2':        /* pass 2 */
  295. X                XARG(argc,argv,argp);            
  296. X                list_Add(pass2PassThrus,argp);
  297. X                break;
  298. X            case 'o':        /* optimizer */
  299. X                XARG(argc,argv,argp);            
  300. X                list_Add(optPassThrus,argp);
  301. X                break;
  302. X            case 'l':        /* linking */
  303. X                XARG(argc,argv,argp);            
  304. X                list_Add(linkPassThrus,argp);
  305. X                break;
  306. X            default:
  307. X                fatal("unknown pass '%c'; must be one of [12ol]",argp[-1]);
  308. X            }
  309. X            break;
  310. X        case 'D':
  311. X            XARG(argc,argv,argp);
  312. X            list_Add(defines,(void *)argp);
  313. X            break;
  314. X        case 'E':
  315. X            warning("-E unimplemented, converted to -P instead");
  316. X            /* fall through */
  317. X        case 'P':
  318. X            options_Clear(OPT_COMPILE);
  319. X            options_Clear(OPT_ASSEMBLE);
  320. X            options_Clear(OPT_LINK);
  321. X            break;
  322. X        case 'g':
  323. X            if(*++argp!='\0') /* optional debuggin level */
  324. X            debugLevel=atoi(argp);
  325. X            options_Set(OPT_DEBUG);
  326. X            break;
  327. X        case 'I':
  328. X            XARG(argc,argv,argp);
  329. X            list_Add(incDirs,(void *)argp);
  330. X            break;
  331. X        case 'l':
  332. X            XARG(argc,argv,argp);
  333. X            list_Add(libs,(void *)argp);
  334. X            break;
  335. X        case 'L':
  336. X            XARG(argc,argv,argp);
  337. X            list_Add(libDirs,(void *)argp);
  338. X            break;
  339. X        case 'B':
  340. X            XARG(argc,argv,argp);
  341. X            list_Add(binDirs,(void *)argp);
  342. X            break;
  343. X        case 'O':
  344. X            options_Set(OPT_OPTIMIZE);
  345. X            break;
  346. X        case 'o':
  347. X            XARG(argc,argv,argp);
  348. X            outfile=argp;
  349. X            break;
  350. X        case 't':        /* warning, non-standard */
  351. X            XARG(argc,argv,argp);
  352. X            tempDir=argp;
  353. X            break;
  354. X        case 'S':
  355. X            warning("-S option not yet implemented, ignored");
  356. X            options_Clear(OPT_ASSEMBLE);
  357. X            break;
  358. X        case 'U':
  359. X            XARG(argc,argv,argp);
  360. X            list_Add(undefines,(void *)argp);
  361. X            break;
  362. X        default:
  363. X            fatal("unknown option '%c'",*argp);
  364. X            break;
  365. X        }
  366. X    }
  367. X
  368. X    DBUG_RETURN(int,list_GetLen(ops));
  369. X}
  370. X
  371. X/*
  372. X *    For each operand, do compilation or assembly as necessary, to
  373. X *    reduce to an object file in the current directory.
  374. X */
  375. Xstatic int makeObjs()
  376. X{
  377. X    int n;
  378. X    void **els;
  379. X    int numOps=list_GetLen(ops);
  380. X    int status=0;
  381. X
  382. X    DBUG_ENTER("makeObjs");
  383. X
  384. X    for(n=numOps,els=list_GetEls(ops); n>0; n--,els++){
  385. X    struct op *op=(struct op *)*els;
  386. X
  387. X    CHECK_ABORT;
  388. X
  389. X    if(numOps>1 && (op_IsC(op) || op_IsS(op)))
  390. X        printf("%s.%s:\n",op->rootname,op->suffix);
  391. X
  392. X    if(op_IsC(op))
  393. X        status=compile(op);
  394. X    else if(op_IsS(op))
  395. X        status=assemble(op);
  396. X    }
  397. X
  398. X    DBUG_RETURN(int,status);
  399. X}
  400. X
  401. X/* handy little routine */
  402. Xvoid addfList(ds,fmt,list)
  403. Xstruct dstr *ds;
  404. Xchar *fmt;
  405. Xstruct list *list;
  406. X{
  407. X    int n;
  408. X    void **els;
  409. X
  410. X    for(n=list_GetLen(list),els=list_GetEls(list); n>0; n--,els++)
  411. X    dstr_Addf(ds,fmt,(char *)*els);
  412. X}
  413. X
  414. X/*
  415. X *    Note that commands to cc of the form "-l<name>" get interpreted
  416. X *    to mean use a library called "name.lib" from the library
  417. X *    directory.
  418. X *      -lm is specially interpreted to be the appropriate math library.
  419. X */
  420. Xstatic int link()
  421. X{
  422. X    int n;
  423. X    void **els;
  424. X
  425. X    DBUG_ENTER("link");
  426. X
  427. X    dstr_Clear(cmdLine);
  428. X
  429. X    dstr_Addf(cmdLine,"%s ",locate("blink",binDirs));
  430. X
  431. X    if(options_IsSet(OPT_DETACH))
  432. X    dstr_Append(cmdLine,locate("cback.o",libDirs));
  433. X    else if(options_IsSet(OPT_RESIDENT)){
  434. X    if(options_IsSet(OPT_CATCH))
  435. X        dstr_Append(cmdLine,locate("catchres.o",libDirs));
  436. X    else
  437. X        dstr_Append(cmdLine,locate("cres.o",libDirs));
  438. X    }else if(options_IsSet(OPT_CATCH))
  439. X    dstr_Append(cmdLine,locate("catch.o",libDirs));
  440. X    else
  441. X    dstr_Append(cmdLine,locate("c.o",libDirs));
  442. X
  443. X    for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
  444. X    struct op *op=(struct op *)*els;
  445. X    char *name=(op_IsO(op) ? op->rootname : op->basename);
  446. X
  447. X    dstr_Addf(cmdLine,"+%s.o",name);
  448. X    }
  449. X
  450. X    if(options_IsSet(OPT_TINYMAIN))
  451. X    dstr_Addf(cmdLine," define __main=__tinymain ");
  452. X
  453. X    dstr_Addf(cmdLine," library ");
  454. X    for(n=list_GetLen(libs),els=list_GetEls(libs); n>0; n--,els++){
  455. X    char buffer[50];
  456. X    char *lib=(char *)*els;
  457. X
  458. X    if(strcmp(lib,"m")==0){
  459. X        /* map -lm to appropiate library */
  460. X
  461. X        strcpy(buffer,"lib:lcm");
  462. X
  463. X        if(options_IsSet(OPT_FFP))
  464. X            strcat(buffer,"ffp");
  465. X        else if(options_IsSet(OPT_IEEE))
  466. X         strcat(buffer,"ieee");
  467. X        else if(options_IsSet(OPT_881))
  468. X        strcat(buffer,"881");
  469. X
  470. X        /*
  471. X         * there are only r and s libraries for lcm.lib in the lattice
  472. X         * distribution; if there is a way to get the lcmieee, lcmffp,
  473. X         * & lcm881 libraries to work with reg-args & short-ints, I
  474. X         * couldn't find it.
  475. X         */
  476. X        if(options_IsSet(OPT_SHORTINTS))
  477. X            strcat(buffer,"s");
  478. X        if(options_IsSet(OPT_REGARGS))
  479. X            strcat(buffer,"r");
  480. X
  481. X        strcat(buffer,".lib");
  482. X    }else if(strcmp(lib,"lc")==0){
  483. X        /* do the standard c library */
  484. X
  485. X        strcpy(buffer,"lib:lc");
  486. X
  487. X        if(options_IsSet(OPT_SHORTINTS))
  488. X            strcat(buffer,"s");
  489. X        if(options_IsSet(OPT_REGARGS))
  490. X            strcat(buffer,"r");
  491. X        if(options_IsSet(OPT_ABSDATA))
  492. X            strcat(buffer,"nb");
  493. X
  494. X        strcat(buffer,".lib");
  495. X
  496. X        if(options_IsSet(OPT_REGARGS)){
  497. X            /*
  498. X             * Now, do it AGAIN, but without registers, to catch any missing refs.
  499. X             * I don't think this is exactly the right thing to do, but there seem
  500. X             * to be internal functions missing from the register-fied libraries
  501. X             */
  502. X
  503. X            strcat(buffer,"+lib:lc");
  504. X
  505. X            if(options_IsSet(OPT_SHORTINTS))
  506. X                strcat(buffer,"s");
  507. X            if(options_IsSet(OPT_ABSDATA))
  508. X                strcat(buffer,"nb");
  509. X
  510. X            strcat(buffer,".lib");
  511. X        }
  512. X    }else{
  513. X        sprintf(buffer,"%s.lib",lib);
  514. X        strcpy(buffer,locate(buffer,libDirs));
  515. X    }        
  516. X
  517. X        if(n==1)
  518. X        dstr_Append(cmdLine,buffer);
  519. X    else
  520. X        dstr_Addf(cmdLine,"%s+",buffer);
  521. X    }
  522. X
  523. X    if(outfile==NULL)
  524. X    /* there better be at least one source file! */
  525. X    outfile=((struct op *)list_GetEls(ops))->basename;
  526. X
  527. X    dstr_Addf(cmdLine," to %s map nil:",outfile);
  528. X
  529. X    addfList(cmdLine," %s",linkPassThrus);
  530. X
  531. X    DBUG_RETURN(int,runCmd(cmdLine));
  532. X}
  533. X
  534. X/*
  535. X *    compile one operand from a C source program to an object module.
  536. X */
  537. Xstatic int compile(op)
  538. Xstruct op *op;
  539. X{
  540. X    int status=0;
  541. X
  542. X    DBUG_ENTER("compile");
  543. X
  544. X    if(options_IsSet(OPT_ASSEMBLE)){
  545. X    status=pass1(op);
  546. X    if(status==0 && options_IsSet(OPT_COMPILE)){
  547. X        CHECK_ABORT;
  548. X        if(options_IsSet(OPT_OPTIMIZE))
  549. X        status=optimize(op);
  550. X        if(status==0)
  551. X            status=pass2(op);
  552. X    }
  553. X    }
  554. X
  555. X    DBUG_RETURN(int,status);
  556. X}
  557. X
  558. X/*
  559. X *    Note that because of brain-damage in the fact that -p to lc1 removes
  560. X *    all predefined defs, we must add them so replacing -c with -P in the
  561. X *    cc command line will result in the same set of predefined symbols.
  562. X *    This is rather ugly and leaves a hole for future problems if we
  563. X *    get out of sync with respect to what names the compiler predefines.
  564. X */
  565. Xstatic int pass1(op)
  566. Xregister struct op *op;
  567. X{
  568. X    char tmpFile[MAXPATH];
  569. X    int status;
  570. X    int n;
  571. X    void **els;
  572. X
  573. X    DBUG_ENTER("pass1");
  574. X
  575. X    dstr_Clear(cmdLine);
  576. X
  577. X    dstr_Append(cmdLine,locate((options_IsSet(OPT_BIGLC1) ? "lc1b" : "lc1"),binDirs));
  578. X
  579. X    if(options_IsSet(OPT_DEBUG)){
  580. X    dstr_Addf(cmdLine," -d%d",debugLevel);
  581. X    if(options_IsSet(OPT_OPTIMIZE)){
  582. X        warning("-g incompatible with -O, -O turned off");
  583. X        options_Clear(OPT_OPTIMIZE);
  584. X    }
  585. X    }
  586. X
  587. X    if(options_IsSet(OPT_FFP))
  588. X    dstr_Addf(cmdLine," -ff");
  589. X    else if(options_IsSet(OPT_881))
  590. X    dstr_Addf(cmdLine," -f8");
  591. X    else if(options_IsSet(OPT_IEEE))
  592. X    dstr_Addf(cmdLine," -fi");
  593. X    else
  594. X    dstr_Addf(cmdLine," -fl");
  595. X
  596. X    if(options_IsSet(OPT_SHORTINTS))
  597. X    dstr_Addf(cmdLine," -w");
  598. X    if(options_IsSet(OPT_LONGALIGN))
  599. X    dstr_Addf(cmdLine," -l");
  600. X
  601. X    if(options_IsSet(OPT_020))
  602. X    dstr_Addf(cmdLine," -m2");
  603. X    else if(options_IsSet(OPT_030))
  604. X    dstr_Addf(cmdLine," -m3");
  605. X
  606. X    if(options_IsSet(OPT_CATCH) && !options_IsSet(OPT_ABSDATA)){
  607. X    warning("+catch implies +abs-data");
  608. X    options_Set(OPT_ABSDATA);
  609. X    }
  610. X
  611. X    dstr_Addf(cmdLine," -b%d",options_IsSet(OPT_ABSDATA) ? 0 : 1);
  612. X    dstr_Addf(cmdLine," -r%d",options_IsSet(OPT_ABSCODE) ? 0 : 1);
  613. X
  614. X    if(options_IsSet(OPT_REGARGS))
  615. X    dstr_Addf(cmdLine,"r"); /* part of -r switch */
  616. X
  617. X    {
  618. X    char buf[15], *p=buf;
  619. X
  620. X    if(options_IsSet(OPT_ANSI))        *p++='a';
  621. X    if(options_IsSet(OPT_CPP))        *p++='+';
  622. X    if(options_IsSet(OPT_TRAD))        *p++='l', *p++='o';
  623. X    if(options_IsSet(OPT_REGARGS))        *p++='r';
  624. X    if(options_IsSet(OPT_PURESTRINGS))    *p++='s';
  625. X    
  626. X    if(p>buf){
  627. X        *p='\0';
  628. X        dstr_Addf(cmdLine," -c%s",buf);
  629. X    }
  630. X    }
  631. X
  632. X    if(options_IsSet(OPT_COMPILE)){
  633. X    strcpy(tmpFile,tempDir);
  634. X    strcat(tmpFile,op->basename);
  635. X    strcat(tmpFile,".q");
  636. X    dstr_Addf(cmdLine," -o%s",tmpFile);
  637. X    }else{
  638. X    strcpy(tmpFile,op->basename);
  639. X    strcat(tmpFile,".pp");
  640. X
  641. X    dstr_Addf(cmdLine," -o%s -p",tmpFile);
  642. X    }
  643. X
  644. X    for(n=list_GetLen(undefines),els=list_GetEls(undefines); n>0; n--,els++){
  645. X    /*************************
  646. X    dstr_Addf(cmdLine," -u%s",(char *)*els);
  647. X    **************************/
  648. X    warning("-U%s ignored! (unimplemented)",(char *)*els);
  649. X    }
  650. X
  651. X    addfList(cmdLine," -d%s",defines);
  652. X    addfList(cmdLine," %s",pass1PassThrus);
  653. X
  654. X    for(n=list_GetLen(incDirs),els=list_GetEls(incDirs); n>0; n--,els++){
  655. X    char *id=(*els);
  656. X    int len=strlen(id);
  657. X
  658. X    dstr_Addf(cmdLine," -i%s",*els);
  659. X
  660. X    if(len>0 && id[len-1]!=':' && id[len-1]!='/')
  661. X        dstr_Addf(cmdLine,"/");
  662. X    }
  663. X
  664. X    dstr_Addf(cmdLine," %s",op->rootname);
  665. X
  666. X    status=runCmd(cmdLine);
  667. X    if(status==0 && options_IsSet(OPT_EXEC) && !readable(tmpFile))
  668. X    status=1;
  669. X
  670. X    DBUG_RETURN(int,status);
  671. X}
  672. X
  673. X/* run the optimizer */
  674. Xstatic int optimize(op)
  675. Xstruct op *op;
  676. X{
  677. X    DBUG_ENTER("optimize");
  678. X
  679. X    dstr_Clear(cmdLine);
  680. X    dstr_Addf(cmdLine,"%s %s%s",locate("go",binDirs),tempDir,op->basename);
  681. X
  682. X    addfList(cmdLine," %s",optPassThrus);
  683. X
  684. X    DBUG_RETURN(int,runCmd(cmdLine));
  685. X}
  686. X
  687. X/*
  688. X *    Run second pass of compiler on a single operand.
  689. X */
  690. Xstatic int pass2(op)
  691. Xstruct op *op;
  692. X{
  693. X    char objFile[MAXPATH];
  694. X    int status;
  695. X
  696. X#ifdef DBUG
  697. X    fprintf(stderr,"Entering pass2...\n");
  698. X#endif
  699. X
  700. X    DBUG_ENTER("pass2");
  701. X
  702. X    dstr_Clear(cmdLine);
  703. X
  704. X    dstr_Append(cmdLine,locate("lc2",binDirs));
  705. X
  706. X    if(!options_IsSet(OPT_STACKCHECK))
  707. X    dstr_Addf(cmdLine," -v");
  708. X
  709. X    strcpy(objFile,op->basename);
  710. X    strcat(objFile,".o");
  711. X
  712. X    dstr_Addf(cmdLine," -o%s",objFile);
  713. X
  714. X    dstr_Addf(cmdLine," %s%s",tempDir,op->basename);
  715. X
  716. X    addfList(cmdLine," %s",pass2PassThrus);
  717. X
  718. X    status=runCmd(cmdLine);
  719. X    if(status==0 && options_IsSet(OPT_EXEC) && !readable(objFile))
  720. X    status=1;
  721. X
  722. X    DBUG_RETURN(int,status);
  723. X}
  724. X
  725. X/*
  726. X *    I have not yet had occasion to use the macro assembler,so this
  727. X *    part is not yet implemented.  If anyone wants to send me the
  728. X *    appropriate code, I will be glad to install it.
  729. X */
  730. Xstatic int assemble(op)
  731. Xstruct op *op;
  732. X{
  733. X    DBUG_ENTER("assemble");
  734. X    warning("assembly pass not yet implemented");
  735. X    DBUG_RETURN(int,1);
  736. X}
  737. X
  738. Xstatic void filteredOutputFrom(source,filter)
  739. XFILE *source;
  740. Xchar **filter;
  741. X{
  742. X    char buf[200];
  743. X
  744. X    DBUG_ENTER("FilteredOutputFrom");
  745. X
  746. X    while(!feof(source)){
  747. X    char **ignore;
  748. X
  749. X    fgets(buf,sizeof(buf),source);
  750. X
  751. X    for(ignore=filter; *ignore!=NULL; ignore++)
  752. X        if(strncmp(*ignore,buf,strlen(*ignore))==0)
  753. X            break;
  754. X
  755. X    if(*ignore==NULL)
  756. X        fputs(buf,stdout);
  757. X    }
  758. X
  759. X    DBUG_VOID_RETURN;
  760. X}
  761. X
  762. X#ifdef AMIGA
  763. X
  764. Xstatic int execToFile(cmd,sink)
  765. Xchar *cmd;
  766. XFILE *sink;
  767. X{
  768. X    /* this is a dopey version that uses Execute, since I can't get fork to work */
  769. X    long fh;
  770. X
  771. X    DBUG_ENTER("execToFile");
  772. X
  773. X    if(sink==NULL)
  774. X    fh=0;
  775. X    else
  776. X    fh=chkufb(fileno(sink))->ufbfh;
  777. X
  778. X    DBUG_RETURN(int,Execute(cmd,0L,fh)!=(-1));
  779. X
  780. X#if 0
  781. X    char *argv[50],**argp=argv;
  782. X    struct ProcID child;
  783. X    static struct FORKENV env={0,0,0,0,0,NULL};
  784. X    int i;
  785. X
  786. X    DBUG_ENTER("execToFile");
  787. X
  788. X    if(cmd==NULL)
  789. X        DBUG_RETURN(int,1);
  790. X
  791. X    /* this is sort of stupid, cause forkv will just put them back together,
  792. X     * but oh well...
  793. X     */
  794. X    *argp=strtok(cmd," \t");
  795. X    while(*argp!=NULL)
  796. X        *++argp=strtok(NULL," \t");
  797. X
  798. X    if(sink==NULL)
  799. X        env.std_out=0;
  800. X    else{
  801. X        struct UFB *ufb=chkufb(fileno(sink));
  802. X    int i;
  803. X
  804. X    printf("argv[%d]:",argp-argv);
  805. X    for(argp=argv;*argp!=NULL;argp++)
  806. X        printf(" %s",*argp);
  807. X    putchar('\n');
  808. X
  809. X    printf("env: %d, %d, %d, %d, %d, %d\n",
  810. X        env.priority, env.stack, env.std_in, env.std_out,
  811. X        env.console, env.msgport);
  812. X
  813. X    printf("ufb==0x%x, fh==0x%x, go? ",ufb,ufb->ufbfh);
  814. X
  815. X    fflush(stdout);
  816. X
  817. X    env.std_out=ufb->ufbfh; /* magic to get amigados handle from FILE */
  818. X    }
  819. X
  820. X    if((i=forkv(argv[0],argv,&env,&child))==-1){
  821. X        poserr("forkv");
  822. X        DBUG_RETURN(int,1);
  823. X    }
  824. X
  825. X    printf("Fork returns: %d\n",i);
  826. X
  827. X    DBUG_RETURN(int,wait(&child));
  828. X#endif
  829. X}
  830. X
  831. X#endif
  832. Xstatic int runCmd(cmd)
  833. Xstruct dstr *cmd;
  834. X{
  835. X    int status;
  836. X    char *buf=dstr_GetBuf(cmd);
  837. X    
  838. X    DBUG_ENTER("RunCommand");
  839. X
  840. X    DBUG_3("cmd","execute '%s'",buf);
  841. X    if(options_IsSet(OPT_ECHO)){
  842. X    puts(buf);
  843. X    fflush(stdout);
  844. X    }
  845. X
  846. X    CHECK_ABORT;
  847. X
  848. X    if(options_IsSet(OPT_EXEC)){
  849. X    FILE *sink;
  850. X
  851. X    if(sinkFile!=NULL && options_IsSet(OPT_FILTER)){
  852. X        sink=fopen(sinkFile,"w+");
  853. X        if(sink==NULL)
  854. X        perror(sinkFile);
  855. X    }else
  856. X        sink=NULL;
  857. X
  858. X    status=execToFile(buf,sink);
  859. X    DBUG_3("sys","subcommand returns status %d",status);
  860. X
  861. X    if(sink!=NULL){
  862. X        rewind(sink);
  863. X        filteredOutputFrom(sink,filteredPrefixes);
  864. X        fclose(sink);
  865. X        unlink(sinkFile);
  866. X    }
  867. X
  868. X    DBUG_RETURN(int,status);
  869. X    }else
  870. X    DBUG_RETURN(int,0);
  871. X}
  872. X
  873. X/*
  874. X *    Look through the list of paths pointed to by "vec" until we find
  875. X *    a file with name given pointed to by "namep".  If none is found,
  876. X *    the name pointed to by namep is returned.
  877. X */
  878. Xstatic char *locate(name,paths)
  879. Xchar *name;
  880. Xstruct list *paths;
  881. X{
  882. X    static char namebuf[MAXPATH];
  883. X    void **els;
  884. X    int n;
  885. X    
  886. X    DBUG_ENTER("locate");
  887. X
  888. X    if(strchr(name,':')!=NULL || *name=='/')
  889. X    return name;    /* absolute */
  890. X    
  891. X    for(n=list_GetLen(paths),els=list_GetEls(paths); n>0; n--,els++){
  892. X    int len=strlen((char *)*els);
  893. X
  894. X    strcpy(namebuf,(char *)*els);
  895. X    if(len>0 && namebuf[len-1]!=':' && namebuf[len-1]!='/')
  896. X        strcat(namebuf,"/");
  897. X    strcat(namebuf,name);
  898. X
  899. X    DBUG_3("try","look for '%s'",namebuf);
  900. X    if(readable(namebuf)){
  901. X        name=namebuf;
  902. X        break;
  903. X    }
  904. X    }
  905. X
  906. X    DBUG_RETURN(char *,name);
  907. X}
  908. X
  909. X/*
  910. X *    Check to see if the file exists and is readable.
  911. X */
  912. Xstatic int readable(name)
  913. Xchar *name;
  914. X{
  915. X    register int status=0;
  916. X    register long fildes;
  917. X    
  918. X    DBUG_ENTER("readable");
  919. X
  920. X#ifdef unix
  921. X    fildes=open(name,O_RDONLY);
  922. X    if(fildes >= 0){
  923. X    (void) close(fildes);
  924. X    status=1;
  925. X    }
  926. X#else
  927. X    fildes=Lock(name,ACCESS_READ);
  928. X    if(fildes != 0){
  929. X        UnLock(fildes);
  930. X    status=1;
  931. X    }
  932. X#endif
  933. X
  934. X    DBUG_RETURN(int,status);
  935. X}
  936. X
  937. X/*
  938. X *    If an executable is made from a single C file, the normal behavior
  939. X *    for the unix environment is to treat the .o file as an intermediate
  940. X *    file and remove it, so we follow suit.
  941. X */
  942. Xstatic void cleanObjects(mustExist)
  943. Xint mustExist;
  944. X{
  945. X    int n;
  946. X    void **els;
  947. X
  948. X    DBUG_ENTER("cleanObjects");
  949. X    
  950. X    for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
  951. X    char buf[MAXPATH];
  952. X        struct op *op=(struct op *)*els;
  953. X
  954. X    if(!op_IsO(op)){
  955. X        strcpy(buf,op->basename);
  956. X        strcat(buf,".o");
  957. X        if(unlink(buf)!=0 && mustExist)
  958. X            warning("can't delete '%s'",buf);
  959. X        }
  960. X    }
  961. X
  962. X    DBUG_VOID_RETURN;
  963. X}
  964. SHAR_EOF
  965. echo "extracting cc.doc"
  966. sed 's/^X//' << \SHAR_EOF > cc.doc
  967. X    CC: a unix-like compiler driver for amiga lattice-c (that also
  968. X        filters out stupid messages!)
  969. X
  970. X    USAGE:
  971. X    cc [args] file...
  972. X
  973. X      Arguments are ([x] means x is optional):
  974. X
  975. X    file        A file to compile or link.  Currently, only .c and .o
  976. X            are understood, although supporting .s files would
  977. X            probably be pretty simple.
  978. X
  979. X    -o execfile    Write the resulting executable to EXECFILE (only
  980. X            meaningful when linking).
  981. X
  982. X    -c        Don't link the object file, just leave it there.
  983. X
  984. X    -g[num]        Compile in debugging info, using debug-level NUM.
  985. X    -O        Use the global optimizer (incompatible with -g).
  986. X    -P        Just pre-process the file, creating a .pp file.
  987. X
  988. X    -l libname    Add LIBNAME.lib to the list of libraries.
  989. X
  990. X    -I dir        Add the directory DIR to the path searched for include
  991. X            files.
  992. X    -D define    Add DEFINE a pre-processor define; it can be just a name
  993. X            or name=value.
  994. X    -U undefin    Undefine the symbol UNDEFINE (this really doesn't work).
  995. X    -L libdir    Add the directory LIBDIR to the path searched for
  996. X            libraries.
  997. X    -B bindir    Add the directory BINDIR to the path searched for
  998. X            binaries.
  999. X
  1000. X    -px string    Put STRING on the command line of compiler pass X, where
  1001. X            X is one of: 1-- pass1; 2-- pass2; o-- optimizer;
  1002. X            and l-- linker.  This switch can be used to get at
  1003. X            compiler features that cc doesn't directly support,
  1004. X            although it'd be better to just add the feature to cc
  1005. X            (it shouldn't be too hard)-- and send the change
  1006. X            back to me (bader+@andrew.cmu.edu)!
  1007. X
  1008. X    -t tempdir    Use TEMPDIR as the place to put temporary files.
  1009. X
  1010. X    +ansi            Enforce ansi fascism.
  1011. X    +cpp            Compat with c++.
  1012. X    +trad            Use traditional style cpp.
  1013. X
  1014. X    +[no-]abs-code        Use long (absolute) addressing for function
  1015. X                calls.
  1016. X    +[no-]abs-data        Use long (absolute) addressing for data.
  1017. X
  1018. X    +[no-]reload-a4        Reload reg a4 in each function.
  1019. X    +[no-]short-ints    Use short integers.
  1020. X    +[no-]reg-args        Use register argument passing.
  1021. X    +[no-]long-align    Align everything to long boundaries.
  1022. X    +[no-]stack-check    Put stack-checking into the func prolog.
  1023. X    +[no-]pure-strings    Put strings in the text segment.
  1024. X
  1025. X    +ffp            Use motorola fast floating point.
  1026. X    +881            Compile for a 68881.
  1027. X    +ieee            Ieee floating point.
  1028. X
  1029. X    +68k            Compile for a 68000 and up.
  1030. X    +020            Compile for a 68020 and up.
  1031. X    +030            Compile for a 68030.
  1032. X
  1033. X    +[no-]detach        Make a program that runs in the background.
  1034. X    +[no-]tiny-main        Use tinymain (this doesn't work).
  1035. X    +[no-]resident        Try and make resident-able.
  1036. X    +[no-]catch        Compile in code to try and catch exceptions.
  1037. X
  1038. X    +[no-]optimize        Optimize the obj module.
  1039. X    +[no-]link        Link the object modules.
  1040. X    +[no-]compile        (Otherwise, just pre-process).
  1041. X    +[no-]assemble        Emit object-modules (else assembly).
  1042. X    +[no-]debug        Produce debugging info.
  1043. X
  1044. X    +[no-]echo        Echo what we execute.
  1045. X    +[no-]filter        Filter out yucky message from passes.
  1046. X    +[no-]exec        Actually run each pass.
  1047. X
  1048. X    +[no-]big-lc1        Run lc1b instead of lc1.
  1049. X
  1050. X    DEFAULTS:
  1051. X        The default options are: +compile +link +stack-check +exec +filter
  1052. X
  1053. X    The default output file is "a.out".
  1054. X
  1055. X    The default temp directory is "t:".
  1056. X
  1057. X    The default debug level when just -g (or +debug) is specified is 3.
  1058. X
  1059. X    The default libraries are: "-lc", "-lamiga".
  1060. X
  1061. X    NOTES:
  1062. X    The library -lm is replaced by whichever math library is appropiate
  1063. X    given other switches (like +ieee or +ffp), and -lc is replaced by
  1064. X    the appropiate c library-- so be and sure to pass the same set of
  1065. X    switches to cc when linking as you do when compiling (with -c) the
  1066. X    object files!
  1067. X
  1068. X    This version of cc is intended for use with lattice c version 5.
  1069. X
  1070. X    BUGS:
  1071. X    I haven't nearly tested all the possible combinations of options.
  1072. X
  1073. X    The libraries supplied by lattice aren't complete, so some combos
  1074. X    of switches may not be possible (e.g., +reg-args and +ieee-- lattice
  1075. X    doesn't supply a libieeer.lib, and so linking fails in this case).
  1076. X
  1077. X    -U doesn't work.
  1078. X
  1079. X    -S doesn't work (and isn't ever likely too unless lattice makes
  1080. X    omd a much better program).
  1081. X
  1082. X    Compiling .s (assembly) files isn't implemented, even though it's
  1083. X    probably pretty simple, using asm.  I just never needed it...
  1084. X
  1085. X    AUTHOR:
  1086. X    Miles Bader (bader+@andrew.cmu.edu)
  1087. X       from an earlier program by Fred Fish.
  1088. SHAR_EOF
  1089. echo "extracting config.h"
  1090. sed 's/^X//' << \SHAR_EOF > config.h
  1091. X/*
  1092. X * configuration file for cc; easily re-configurable stuff goes here.
  1093. X * March 1989, Miles Bader
  1094. X */
  1095. X
  1096. X/*
  1097. X * this file contains declarations, so it can only be included in one source file
  1098. X */
  1099. X
  1100. X#define MAXPATH 200        /* max length of a path */
  1101. X
  1102. X/* What to call executable if not specified.  If NULL, named after 1st source file */
  1103. X#define DEFAULT_EXEC "a.out"
  1104. X/* must be a prefix; i.e., needs a slash or a colon on the end */
  1105. X#define TEMPDIR    "T:"        /* Keep intermediate files in temp directory */
  1106. X/* #define TEMPDIR "" */    /* Keep intermediate files in current dir */
  1107. X
  1108. X/* The file for filtering compiler pass output.  If NULL, no filtering is done */
  1109. X#define SINKFILE "T:__cc_sink"
  1110. X
  1111. X#define DEFAULT_DEBUGLEVEL 3    /* default debug level if just -g is given */
  1112. X
  1113. X/* Listf of default options.  Note that not having _EXEC, _COMPILE, _ASSEMBLE,
  1114. X * and _LINK set by default would be very wierd
  1115. X */
  1116. Xint defaultOptions[]={
  1117. X    OPT_COMPILE,    /* compile things! */
  1118. X    OPT_ASSEMBLE,    /* make object files! */
  1119. X    OPT_EXEC,        /* execute passes! */
  1120. X    OPT_LINK,        /* link into executable! */
  1121. X    OPT_FILTER,        /* filter out obnoxious messages */
  1122. X    OPT_STACKCHECK,    /* enable stack checking */
  1123. X    0
  1124. X};
  1125. X
  1126. X/* initial contents of some lists; &insertMark is where additional elements go */
  1127. Xchar *libDirsInit[]={"",&insertMark,"lib:",NULL};
  1128. Xchar *incDirsInit[]={&insertMark,"include:",NULL};
  1129. Xchar **binDirsInit=NULL;
  1130. Xchar **definesInit=NULL;
  1131. Xchar **undefinesInit=NULL;
  1132. Xchar *libsInit[]={&insertMark,"lc","amiga",NULL};
  1133. X
  1134. X/* prefixes that are filtered out of the compiler output stream */
  1135. Xchar *filteredPrefixes[]={
  1136. X    "\n",            /* blank lines */
  1137. X    "Copyright",        /* copyright noticed */
  1138. X    "Lattice",            /* lattice advertisements */
  1139. X
  1140. X    /* lc2 */
  1141. X    "Module size",
  1142. X
  1143. X    /* blink */
  1144. X    "Blink - Version",
  1145. X    "Enter a DEFINE value",     /* input is impossible anyway... */
  1146. X    "BLINK Complete",
  1147. X    "Final output file size",
  1148. X    NULL
  1149. X};
  1150. SHAR_EOF
  1151. echo "extracting dstr.c"
  1152. sed 's/^X//' << \SHAR_EOF > dstr.c
  1153. X/*
  1154. X * dynamic strings
  1155. X * March 1989, Miles Bader
  1156. X */
  1157. X
  1158. X#include "common.h"
  1159. X#include "dstr.h"
  1160. X
  1161. Xstruct dstr *dstr_Create(initsize)
  1162. Xint initsize;
  1163. X{
  1164. X    struct dstr *n=NEW(struct dstr);
  1165. X    
  1166. X    DBUG_ENTER("dstr_Create");
  1167. X
  1168. X    if(n==NULL)
  1169. X    fatal("couldn't allocate a dstr");
  1170. X
  1171. X    n->buf=malloc(initsize+1);
  1172. X
  1173. X    if(n->buf==NULL)
  1174. X    fatal("couldn't allocate dstr of size %d",initsize);
  1175. X
  1176. X    n->max=initsize;
  1177. X    n->len=0;
  1178. X    *n->buf='\0';
  1179. X
  1180. X    DBUG_RETURN(struct dstr *,n);
  1181. X}
  1182. X
  1183. Xvoid dstr_Free(ds)
  1184. Xstruct dstr *ds;
  1185. X{
  1186. X    DBUG_ENTER("dstr_Free");
  1187. X
  1188. X    if(ds->buf!=NULL)
  1189. X    FREE(ds->buf);
  1190. X    FREE(ds);
  1191. X
  1192. X    DBUG_VOID_RETURN;
  1193. X}
  1194. X
  1195. Xvoid dstr_Clear(ds)
  1196. Xstruct dstr *ds;
  1197. X{
  1198. X   ds->len=0;
  1199. X   *ds->buf='\0';
  1200. X}
  1201. X
  1202. Xvoid dstr_Append(ds,str)
  1203. Xstruct dstr *ds;
  1204. Xchar *str;
  1205. X{
  1206. X    int len=strlen(str);
  1207. X    
  1208. X    DBUG_ENTER("dstr_Append");
  1209. X
  1210. X    if(len+ds->len>ds->max){
  1211. X    ds->max+=len+len;
  1212. X    ds->buf=(char *)realloc((void *)ds->buf,ds->max);
  1213. X
  1214. X    if(ds->buf==NULL)
  1215. X        fatal("couldn't extend a dstr to %d chars",ds->max);
  1216. X    }
  1217. X
  1218. X    strcpy(ds->buf+ds->len,str);
  1219. X    ds->len+=len;
  1220. X
  1221. X    DBUG_VOID_RETURN;
  1222. X}
  1223. X
  1224. Xvoid dstr_Set(ds,str)
  1225. Xstruct dstr *ds;
  1226. Xchar *str;
  1227. X{
  1228. X    DBUG_ENTER("dstr_Set");
  1229. X
  1230. X    ds->len=0;
  1231. X    dstr_Append(ds,str);
  1232. X
  1233. X    DBUG_VOID_RETURN;
  1234. X}
  1235. X
  1236. Xvoid dstr_Addf(ds,fmt,a1,a2,a3,a4,a5,a6,a7)
  1237. Xstruct dstr *ds;
  1238. Xchar *fmt;
  1239. Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
  1240. X{
  1241. X    char buf[500];
  1242. X
  1243. X    DBUG_ENTER("dstr_Addf");
  1244. X
  1245. X    sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7);
  1246. X
  1247. X    DBUG_2("buf",buf);
  1248. X
  1249. X    dstr_Append(ds,buf);
  1250. X
  1251. X    DBUG_VOID_RETURN;
  1252. X}
  1253. SHAR_EOF
  1254. echo "extracting dstr.h"
  1255. sed 's/^X//' << \SHAR_EOF > dstr.h
  1256. X/*
  1257. X * dynamic strings
  1258. X * March 1989, Miles Bader
  1259. X */
  1260. X
  1261. Xstruct dstr {
  1262. X    int max,len;
  1263. X    char *buf;
  1264. X};
  1265. X
  1266. Xstruct dstr *dstr_Create();
  1267. Xvoid dstr_Free();
  1268. Xvoid dstr_Clear();
  1269. Xvoid dstr_Set();
  1270. Xvoid dstr_Append();
  1271. Xvoid dstr_Addf();
  1272. X
  1273. X#define dstr_GetBuf(d) ((d)->buf)
  1274. X#define dstr_GetLen(d) ((d)->len)
  1275. SHAR_EOF
  1276. echo "extracting err.c"
  1277. sed 's/^X//' << \SHAR_EOF > err.c
  1278. X/*
  1279. X * these are in a separate file so the compiler doesn't bitch about mismatched
  1280. X * arguments
  1281. X */
  1282. X
  1283. X#include <stdio.h>
  1284. X
  1285. X#include "common.h"
  1286. X
  1287. X/*VARARGS1*/
  1288. Xvoid warning(fmt,a1,a2,a3,a4,a5,a6,a7)
  1289. Xchar *fmt;
  1290. Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
  1291. X{
  1292. X    fputs("cc: warning: ",stderr);
  1293. X    fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
  1294. X    putc('\n',stderr);
  1295. X    (void) fflush(stderr);
  1296. X}
  1297. X
  1298. X/*VARAS1*/
  1299. Xvoid fatal(fmt,a1,a2,a3,a4,a5,a6,a7)
  1300. Xchar *fmt;
  1301. Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
  1302. X{
  1303. X    fputs("cc: error: ",stderr);
  1304. X    fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
  1305. X    putc('\n',stderr);
  1306. X    (void) fflush(stderr);
  1307. X    exit(1);
  1308. X}
  1309. SHAR_EOF
  1310. echo "extracting list.c"
  1311. sed 's/^X//' << \SHAR_EOF > list.c
  1312. X/*
  1313. X * expandable lists
  1314. X * March 1989, Miles Bader
  1315. X */
  1316. X
  1317. X#include "common.h"
  1318. X#include "list.h"
  1319. X
  1320. X#define BUMPSIZE 5            /* grow list this much at a time */
  1321. X
  1322. Xchar insertMark;            /* dummy used for its address */
  1323. X
  1324. Xstruct list *list_Create(init)
  1325. Xvoid **init;
  1326. X{
  1327. X    void **p,**q;
  1328. X    struct list *l=NEW(struct list);
  1329. X    
  1330. X    DBUG_ENTER("list_Create");
  1331. X
  1332. X    if(l==NULL)
  1333. X    fatal("couldn't allocate a list");
  1334. X
  1335. X    l->num=0;
  1336. X
  1337. X    l->insertionPoint=(-1);
  1338. X
  1339. X    for(p=init; p!=NULL && *p!=NULL; p++)
  1340. X    if(*p==&insertMark)
  1341. X        l->insertionPoint=l->num;
  1342. X    else
  1343. X        l->num++;
  1344. X
  1345. X    l->els=(void **)malloc(l->num*sizeof(void *));
  1346. X
  1347. X    if(l->els==NULL && l->num>0 /* ANSI compat */)
  1348. X    fatal("couldn't allocate initial list elements");
  1349. X
  1350. X    for(p=init,q=l->els; p!=NULL && *p!=NULL; p++)
  1351. X    if(*p!=&insertMark)
  1352. X        *q++=(*p);
  1353. X
  1354. X    l->max=l->num;
  1355. X    if(l->insertionPoint<0)
  1356. X    l->insertionPoint=l->num;     /* default is at end */
  1357. X
  1358. X    l->freeProc=NULL;
  1359. X
  1360. X    DBUG_RETURN(struct list *,l);
  1361. X}
  1362. X
  1363. Xvoid list_Free(l)
  1364. Xstruct list *l;
  1365. X{
  1366. X    DBUG_ENTER("list_Free");
  1367. X
  1368. X    if(l->freeProc!=NULL){
  1369. X        void **els;
  1370. X    int n;
  1371. X    
  1372. X    DBUG_4("free","using freeProc on %d els: 0x%x",l->num,l->freeProc);
  1373. X
  1374. X    for(n=l->num,els=l->els; n>0; n--,els++){
  1375. X        DBUG_3("free","freeProc(0x%x)",*els);
  1376. X        (*l->freeProc)(*els);
  1377. X    }
  1378. X    }
  1379. X
  1380. X    if(l->els!=NULL){
  1381. X        DBUG_3("free","freeing els: 0x%x",l->els);
  1382. X    FREE(l->els);
  1383. X    }
  1384. X
  1385. X    DBUG_3("free","freeing list: 0x%x",l);
  1386. X
  1387. X    FREE(l);
  1388. X
  1389. X    DBUG_VOID_RETURN;
  1390. X}
  1391. X
  1392. Xvoid list_Add(l,e)
  1393. Xstruct list *l;
  1394. Xvoid *e;
  1395. X{
  1396. X    int i;
  1397. X    
  1398. X    DBUG_ENTER("list_Add");
  1399. X
  1400. X    if(l->num>=l->max){
  1401. X        l->max+=BUMPSIZE;
  1402. X    l->els=(void **)realloc((void *)l->els,l->max*sizeof(void *));
  1403. X
  1404. X    if(l->els==NULL)
  1405. X        fatal("couldn't extend a list to %d elements",l->max);
  1406. X    }
  1407. X
  1408. X    for(i=l->num; i>l->insertionPoint; i--)
  1409. X    l->els[i]=l->els[i-1];
  1410. X
  1411. X    l->els[l->insertionPoint++]=e;
  1412. X
  1413. X    l->num++;
  1414. X
  1415. X    DBUG_VOID_RETURN;
  1416. X}
  1417. SHAR_EOF
  1418. echo "extracting list.h"
  1419. sed 's/^X//' << \SHAR_EOF > list.h
  1420. X/*
  1421. X * expandable lists
  1422. X * March 1989, Miles Bader
  1423. X */
  1424. X
  1425. Xextern char insertMark;
  1426. X
  1427. Xstruct list {
  1428. X    int num,max;
  1429. X    int insertionPoint;            /* where a new element gets added */
  1430. X    void **els;
  1431. X    void (*freeProc)();            /* if non-NULL, used to free elements */
  1432. X};
  1433. X
  1434. Xstruct list *list_Create(void **initEls);
  1435. Xvoid list_Free(struct list *l);
  1436. Xvoid list_Add(struct list *l,void *el);
  1437. X
  1438. X#define list_GetEls(l) ((l)->els)
  1439. X#define list_GetLen(l) ((l)->num)
  1440. X
  1441. X#define list_SetFree(l,fp) ((l)->freeProc=fp)
  1442. SHAR_EOF
  1443. echo "extracting op.c"
  1444. sed 's/^X//' << \SHAR_EOF > op.c
  1445. X/*
  1446. X * file operands
  1447. X * March 1989, Miles Bader (orig from cc.c by fred fish)
  1448. X */
  1449. X
  1450. X#include "common.h"
  1451. X#include "op.h"
  1452. X
  1453. X/*
  1454. X *    Split an operand name into rootname, basename, and suffix
  1455. X *    components.  The rootname is the full name, minus any suffix,
  1456. X *    but including any prefix.  The basename is the rootname minus
  1457. X *    any prefix.  The suffix is anything after the last '.' character.
  1458. X *    Only the suffix is allowed to be the null string.
  1459. X */
  1460. Xstruct op *op_Create(filename)
  1461. Xchar *filename;
  1462. X{
  1463. X    char *split;
  1464. X    extern char *strrchr();
  1465. X    struct op *op=NEW(struct op);
  1466. X
  1467. X    DBUG_ENTER("op_Create");
  1468. X
  1469. X    DBUG_3("ops", "create op '%s'",filename);
  1470. X
  1471. X    if(op==NULL)
  1472. X    fatal("couldn't allocate an op");
  1473. X
  1474. X    op->rootname=filename;
  1475. X
  1476. X    split=strrchr(filename,'/');
  1477. X    if(split==NULL)
  1478. X    split=strrchr(filename,':');
  1479. X
  1480. X    if(split==NULL)
  1481. X    op->basename=filename;
  1482. X    else
  1483. X    op->basename=++split;
  1484. X
  1485. X    split=strrchr(filename,'.');
  1486. X    if(split==NULL)
  1487. X    op->suffix="";
  1488. X    else{
  1489. X    *split++='\0';
  1490. X    op->suffix=split;
  1491. X    }
  1492. X
  1493. X    DBUG_3("ops","rootname '%s'",op->rootname);
  1494. X    DBUG_3("ops","basename '%s'",op->basename);
  1495. X    DBUG_3("ops","suffix '%s'",op->suffix);
  1496. X
  1497. X    DBUG_RETURN(struct op *,op);
  1498. X}
  1499. X
  1500. Xvoid op_Free(op)
  1501. Xstruct op *op;
  1502. X{
  1503. X    FREE(op);
  1504. X}
  1505. SHAR_EOF
  1506. echo "extracting op.h"
  1507. sed 's/^X//' << \SHAR_EOF > op.h
  1508. X/*
  1509. X * file operands
  1510. X * March 1989, Miles Bader (orig from cc.c by fred fish)
  1511. X */
  1512. X
  1513. X/*
  1514. X *    Command line arguments that represent files to be compiled, assembled,
  1515. X *    or linked, are kept track of as "ops".  If, for example,
  1516. X *    the file name is "df0:mydir/junk.c", then the rootname is
  1517. X *    "df0:mydir/junk", the basename is "junk", and the suffix is "c".
  1518. X *    String suffixes are used, rather than single character suffixes, to
  1519. X *    allow use of names with multicharacter suffixes.
  1520. X */
  1521. X
  1522. Xstruct op{        /* Info about each operand (non option) */
  1523. X    char *rootname;        /* Name minus any suffix */
  1524. X    char *basename;        /* Name minus any prefix or suffix */
  1525. X    char *suffix;        /* suffix of operand */
  1526. X};
  1527. X
  1528. X/*
  1529. X *    macros to determine the suffix type of a file given a pointer to
  1530. X *    its operand structure.
  1531. X */
  1532. X#define op_IsC(op) (strcmp(op->suffix,"c")==0)
  1533. X#define op_IsS(op) (strcmp(op->suffix,"s")==0)
  1534. X#define op_IsO(op) (strcmp(op->suffix,"o")==0)
  1535. X
  1536. Xstruct op *op_Create(char *name);
  1537. Xvoid op_Free(struct op *op);
  1538. SHAR_EOF
  1539. echo "extracting options.c"
  1540. sed 's/^X//' << \SHAR_EOF > options.c
  1541. X/*
  1542. X * compiler options processing
  1543. X * March 1989, Miles Bader
  1544. X */
  1545. X
  1546. X#include "common.h"
  1547. X#include "options.h"
  1548. X
  1549. Xlong globalOpts[MAXOPTS/BITSPERLONG];
  1550. X
  1551. Xstruct option {
  1552. X    char *name;
  1553. X    int opt;
  1554. X    int *set;
  1555. X};
  1556. X
  1557. X/* pre-processor compatibility modes */
  1558. Xint ppOptSet[]={OPT_TRAD, OPT_ANSI, OPT_CPP, 0};
  1559. X
  1560. X/* cpu-types */
  1561. Xint cpuOptSet[]={OPT_68K, OPT_020, OPT_030, 0};
  1562. X
  1563. X/* types of floating point support */
  1564. Xint floatOptSet[]={OPT_FFP, OPT_IEEE, OPT_881, 0};
  1565. X
  1566. Xstruct option optionlist[]={
  1567. X/*   name        mask        excludes    */
  1568. X
  1569. X    /* parsing */
  1570. X    {"ansi",        OPT_ANSI,    ppOptSet},
  1571. X    {"c++",        OPT_CPP,    ppOptSet},
  1572. X    {"traditional",    OPT_TRAD,    ppOptSet},
  1573. X
  1574. X    /* code gen */
  1575. X    {"abs-code",    OPT_ABSCODE},
  1576. X    {"abs-data",    OPT_ABSDATA},
  1577. X
  1578. X    {"reg-args",    OPT_REGARGS},
  1579. X    {"reload-a4",    OPT_RELOADA4},
  1580. X    {"short-ints",    OPT_SHORTINTS},
  1581. X    {"long-align",    OPT_LONGALIGN},
  1582. X    {"stack-check",    OPT_STACKCHECK},
  1583. X
  1584. X    {"pure-strings",    OPT_PURESTRINGS},
  1585. X
  1586. X    {"68k",        OPT_68K,    cpuOptSet},
  1587. X    {"020",        OPT_020,    cpuOptSet},
  1588. X    {"030",        OPT_030,    cpuOptSet},
  1589. X
  1590. X    {"881",        OPT_881,    floatOptSet},
  1591. X    {"ffp",        OPT_FFP,    floatOptSet},
  1592. X    {"ieee",        OPT_IEEE,    floatOptSet},
  1593. X
  1594. X    /* linking */
  1595. X    {"detach",        OPT_DETACH},
  1596. X    {"resident",    OPT_RESIDENT},
  1597. X    {"tiny-main",    OPT_TINYMAIN},
  1598. X    {"catch",        OPT_CATCH},
  1599. X
  1600. X    {"optimize",    OPT_OPTIMIZE},
  1601. X    {"link",        OPT_LINK},
  1602. X    {"compile",        OPT_COMPILE},
  1603. X    {"assemble",    OPT_ASSEMBLE},
  1604. X    {"debug",        OPT_DEBUG},
  1605. X
  1606. X    {"echo",        OPT_ECHO},
  1607. X    {"filter",        OPT_FILTER},
  1608. X    {"exec",        OPT_EXEC},
  1609. X
  1610. X    {"big-lc1",        OPT_BIGLC1},
  1611. X
  1612. X    NULL
  1613. X};
  1614. X
  1615. Xvoid options_SetByName(optname)
  1616. Xchar *optname;
  1617. X{
  1618. X    struct option *opt;
  1619. X    int not=FALSE;
  1620. X
  1621. X    if(strncmp(optname,"no-",3)==0){
  1622. X    optname+=3;
  1623. X    not=TRUE;
  1624. X    }
  1625. X
  1626. X    for(opt=optionlist; opt->name!=NULL; opt++)
  1627. X    if(strcmp(optname,opt->name)==0){
  1628. X        if(not){
  1629. X        if(opt->set!=NULL)
  1630. X            fatal("%s is not a boolean option",opt);
  1631. X        else
  1632. X            options_Clear(opt->opt);
  1633. X        }else{
  1634. X        if(opt->set!=NULL){
  1635. X            int *clear;
  1636. X            for(clear=opt->set; *clear!=0; clear++)
  1637. X                options_Clear(*clear);
  1638. X        }
  1639. X        
  1640. X        options_Set(opt->opt);
  1641. X        }
  1642. X
  1643. X        break;
  1644. X    }
  1645. X
  1646. X    if(opt->name==NULL)
  1647. X    fatal("unknown option: %s",optname);
  1648. X}
  1649. X
  1650. Xvoid options_Init()
  1651. X{
  1652. X    int i;
  1653. X    for(i=0; i<(MAXOPTS/BITSPERLONG); i++)
  1654. X    globalOpts[i]=0;
  1655. X}
  1656. SHAR_EOF
  1657. echo "extracting options.h"
  1658. sed 's/^X//' << \SHAR_EOF > options.h
  1659. X/*
  1660. X * compiler options
  1661. X * March 1989, Miles Bader
  1662. X */
  1663. X
  1664. X/* increase this for more options */
  1665. X#define MAXOPTS    64
  1666. X
  1667. X#ifndef BITSPERLONG
  1668. X#define BITSPERLONG 32
  1669. X#endif
  1670. X
  1671. Xextern long globalOpts[MAXOPTS/BITSPERLONG];
  1672. X
  1673. X#define options_IsSet(opt) \
  1674. X (globalOpts[(opt)/BITSPERLONG]&(1L<<((opt)%BITSPERLONG)))
  1675. X#define options_Set(opt) \
  1676. X (globalOpts[(opt)/BITSPERLONG]|=(1L<<((opt)%BITSPERLONG)))
  1677. X#define options_Clear(opt) \
  1678. X (globalOpts[(opt)/BITSPERLONG]&=~(1L<<(long)((opt)%BITSPERLONG)))
  1679. X
  1680. Xvoid options_SetByName(char *optname);
  1681. Xvoid options_Init();
  1682. X
  1683. X
  1684. X#define OPT_NONE    0
  1685. X
  1686. X#define OPT_ANSI    1    /* enforce ansi fascism */
  1687. X#define OPT_CPP        2    /* compat with c++ */
  1688. X#define OPT_TRAD    3    /* use traditional style cpp */
  1689. X
  1690. X#define OPT_ABSCODE    4    /* use long (absolute) addressing for function calls */
  1691. X#define OPT_ABSDATA    5    /* use long (absolute) addressing for data */
  1692. X
  1693. X#define OPT_RELOADA4    6    /* reload reg a4 in each function */
  1694. X#define OPT_SHORTINTS    7    /* use short integers */
  1695. X#define OPT_REGARGS    8    /* use register argument passing */
  1696. X#define OPT_LONGALIGN    9    /* align everything to long boundaries */
  1697. X#define OPT_STACKCHECK    10    /* put stack-checking into the func prolog */
  1698. X#define OPT_PURESTRINGS    11    /* put strings in the text segment */
  1699. X
  1700. X#define OPT_FFP        12    /* use mot fast floating point */
  1701. X#define OPT_881        13    /* compile for a 68881 */
  1702. X#define OPT_IEEE    14    /* ieee floating point */
  1703. X
  1704. X#define OPT_68K        15    /* compile for a 68000 and up */
  1705. X#define OPT_020        16    /* compile for a 68020 and up */
  1706. X#define OPT_030        17    /* compile for a 68030 */
  1707. X
  1708. X#define OPT_DETACH    18    /* make a program that runs in the background */
  1709. X#define OPT_TINYMAIN    19    /* use tinymain (this doesn't work) */
  1710. X#define OPT_RESIDENT    20    /* try and make resident-able */
  1711. X#define OPT_CATCH    21    /* compile in code to try and catch exceptions */
  1712. X
  1713. X#define OPT_OPTIMIZE    22    /* optimize the obj module */
  1714. X#define OPT_LINK    23    /* link the object modules */
  1715. X#define OPT_COMPILE    24    /* (otherwise, just pre-process) */
  1716. X#define OPT_ASSEMBLE    25    /* emit object-modules (else assembly) */
  1717. X#define OPT_DEBUG    26    /* produce debugging info */
  1718. X
  1719. X#define OPT_ECHO    27    /* echo what we execute */
  1720. X#define OPT_FILTER    28    /* filter out yucky message from passes */
  1721. X#define OPT_EXEC    29    /* actually run each pass */
  1722. X
  1723. X#define OPT_BIGLC1    30    /* run lc1b instead of lc1 */
  1724. SHAR_EOF
  1725. echo "End of archive 1 (of 1)"
  1726. # if you want to concatenate archives, remove anything after this line
  1727. exit
  1728.